package com.zzy.commons;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;

public class IOUtils {

	private static final int NIO_BUFFER_LIMIT = 8 * 1024;

	public static Object toObject(byte[] buffer) throws Exception {
		ByteArrayInputStream byteIn = null;
		ObjectInputStream in = null;

		byteIn = new ByteArrayInputStream(buffer);
		in = new ObjectInputStream(byteIn);
		Object object = in.readObject();
		in.close();
		byteIn.close();
		return object;
		

	}

	public static byte[] toByte(Object object) throws Exception {
		ByteArrayOutputStream byteOut = null;
		ObjectOutputStream out = null;
		byteOut = new ByteArrayOutputStream();
		out = new ObjectOutputStream(byteOut);
		out.writeObject(object);
		out.flush();
		byte[] buffer = byteOut.toByteArray();

		int length = buffer.length;
		byte header[] = intToBytes2(length);
		byte[] all = new byte[buffer.length + header.length];
		System.arraycopy(header, 0, all, 0, header.length);
		System.arraycopy(buffer, 0, all, header.length, buffer.length);
		out.close();
		byteOut.close();
		return all;
	}

	public static byte[] intToBytes2(int n) {
		byte[] b = new byte[4];
		for (int i = 0; i < 4; i++) {
			b[i] = (byte) (n >> (24 - i * 8));
		}
		return b;
	}

	public static int channelIO(ReadableByteChannel readCh,
			WritableByteChannel writeCh, ByteBuffer buf) throws IOException {

		int originalLimit = buf.limit();
		int initialRemaining = buf.remaining();
		int ret = 0;

		while (buf.remaining() > 0) {
			try {
				int ioSize = Math.min(buf.remaining(), NIO_BUFFER_LIMIT);
				buf.limit(buf.position() + ioSize);

				ret = (readCh == null) ? writeCh.write(buf) : readCh.read(buf);

				if (ret < ioSize) {
					break;
				}

			} finally {
				buf.limit(originalLimit);
			}
		}

		int nBytes = initialRemaining - buf.remaining();
		return (nBytes > 0) ? nBytes : ret;
	}
}
